package mylab.utils.common;


import java.util.regex.Pattern;

import lombok.experimental.UtilityClass;
import lombok.extern.slf4j.Slf4j;

@Slf4j
@UtilityClass
public class SqlStringUtil {

    public static void main(String[] args) {
        // 正常输入
        System.out.println(hasSqlInjection("john.doe")); // false

        // SQL注入尝试
        System.out.println(hasSqlInjection("' OR 1=1 --")); // true
        System.out.println(hasSqlInjection("/* comment */")); // true
        System.out.println(hasSqlInjection("union select * from users")); // true
    }

    public String camelToUnderline(String param) {
        if (StringUtil.isEmpty(param)) {
            return StringUtil.EMPTY;
        } else {
            int len = param.length();
            StringBuilder sb = new StringBuilder(len);

            for (int i = 0; i < len; ++i) {
                char c = param.charAt(i);
                if (Character.isUpperCase(c) && i > 0) {
                    sb.append('_');
                }

                sb.append(Character.toLowerCase(c));
            }

            return sb.toString();
        }
    }

    // 下划线 to 驼峰
    public String underlineToCamel(String param) {
        if (StringUtil.isEmpty(param)) {
            return StringUtil.EMPTY;
        } else {
            String temp = param.toLowerCase();
            int len = temp.length();
            StringBuilder sb = new StringBuilder(len);

            for (int i = 0; i < len; ++i) {
                char c = temp.charAt(i);
                if (c == '_') {
                    ++i;
                    if (i < len) {
                        sb.append(Character.toUpperCase(temp.charAt(i)));
                    }
                } else {
                    sb.append(c);
                }
            }

            return sb.toString();
        }
    }

    // 转义 SQL 字符串中的特殊字符
    public String escapeSql(String input) {
        if (input == null) {
            return null;
        }
        // 转义单引号、反斜杠等
        return input.replace("'", "''")
                .replace("\\", "\\\\")
                .replace("%", "\\%")
                .replace("_", "\\_");
    }

    // 验证输入是否包含 SQL 注入风险
    public boolean hasSqlInjection(String input) {
        if (input == null) {
            return false;
        }
        Pattern SQL_INJECTION_PATTERN= Pattern.compile("\\b(and|exec|insert|select|drop|grant|alter|delete|update|count|chr|mid|master|truncate|char|declare|or)\\b|([*;+'%])");
        return SQL_INJECTION_PATTERN.matcher(input).find();
    }

    // 安全构建 LIKE 查询条件
    public String buildLikeCondition(String keyword) {
        if (keyword == null) {
            return null;
        }
        // 先转义特殊字符，再添加通配符
        return "%" + escapeSql(keyword) + "%";
    }

    // 安全构建 IN 子句
    public String buildInClause(int parameterCount) {
        if (parameterCount <= 0) {
            return "()";
        }
        StringBuilder sb = new StringBuilder("(");
        for (int i = 0; i < parameterCount; i++) {
            if (i > 0) {
                sb.append(", ");
            }
            sb.append("?");
        }
        sb.append(")");
        return sb.toString();
    }

    // 安全构建 IN 子句（直接使用值，不推荐，有 SQL 注入风险）
    public String buildInClauseWithValues(Object... values) {
        if (values == null || values.length == 0) {
            return "()";
        }
        StringBuilder sb = new StringBuilder("(");
        for (int i = 0; i < values.length; i++) {
            if (i > 0) {
                sb.append(", ");
            }
            if (values[i] instanceof String) {
                sb.append("'").append(escapeSql(values[i].toString())).append("'");
            } else {
                sb.append(values[i]);
            }
        }
        sb.append(")");
        return sb.toString();
    }

    // 格式化 SQL 查询（用于日志或调试）
    public String formatSql(String sql, Object... params) {
        if (sql == null || params == null || params.length == 0) {
            return sql;
        }
        StringBuilder formatted = new StringBuilder(sql);
        int paramIndex = 0;
        int questionMarkIndex = formatted.indexOf("?");

        while (questionMarkIndex != -1 && paramIndex < params.length) {
            Object param = params[paramIndex];
            String paramValue = param == null ? "NULL" :
                    (param instanceof String ? "'" + param + "'" : param.toString());

            formatted.replace(questionMarkIndex, questionMarkIndex + 1, paramValue);
            paramIndex++;
            questionMarkIndex = formatted.indexOf("?", questionMarkIndex + paramValue.length());
        }

        return formatted.toString();
    }
}
